from django import http
from django.shortcuts import render
from django.views import View
import json
import pickle
import base64

# Create your views here.
from django.views.decorators.csrf import csrf_exempt

from goods.models import SKU
from meiduo_mall.utils.response_code import RET
from django_redis import get_redis_connection


class CartsView(View):

    @csrf_exempt
    def post(self, request):

        data_dict = json.loads(request.body)

        sku_id = data_dict.get('sku_id')
        count = data_dict.get('count')

        if not all([sku_id, count]):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '参数不全'})

        # 判断商品是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return http.JsonResponse({'code': RET.DBERR, 'errmsg': '商品不存在'})

        try:
            count = int(count)
        except:
            return http.JsonResponse({'code': RET.DATAERR, 'errmsg': '参数有误'})

        # 库存是否足够
        if count > sku.stock:
            return http.JsonResponse({'code': RET.DATAERR, 'errmsg': '库存不足'})

        print(request.user.is_authenticated)

        if request.user.is_authenticated:
            # 用户登录的情况下
            redis_conn = get_redis_connection('carts')
            # field存在，则增加，不存在就添加
            # 存储商品的购买数
            print(count)
            redis_count = redis_conn.hget('carts_%s' % request.user.id, sku_id)
            if redis_count:
                count += int(redis_count)
            if count > 5:
                redis_conn.hset('carts_%s' % request.user.id, sku_id, 5)
            else:
                redis_conn.hset('carts_%s' % request.user.id, sku_id, count)
            # 商品被选中
            redis_conn.sadd('selected_%s' % request.user.id, sku_id)

            return http.JsonResponse({'code': RET.OK})
        else:
            # 未登录用户将购物车信息存到cookie里
            cookie_cart = request.COOKIES.get('carts')
            """
            cookie_cart 格式 是
            cookie_cart = {
                "sku_id": {
                    "count": count,
                    "selected": selected,
                }
            } 通过base.b64encode().decode()加密后的数据
            gAN9cQBLEH1xAShYBQAAAGNvdW50cQJLA1gIAAAAc2VsZWN0ZWRxA4h1cy4=
            """
            cookie_cart_cart = {}
            if cookie_cart:
                # 将6位二进制数转8位 使用base64.b64encode(6为二进制数)
                print(cookie_cart)
                print(cookie_cart.encode())
                print(base64.b64decode(cookie_cart.encode()))
                cookie_cart_cart = pickle.loads(base64.b64decode(cookie_cart.encode()))
                print(cookie_cart_cart)
                print(type(cookie_cart_cart))

            if sku_id in cookie_cart_cart:
                old_count = cookie_cart_cart[sku_id]['count']
                count += old_count
            cookie_cart_cart[sku_id] = {
                'count': count,
                'selected': True
            }
        response = http.JsonResponse({'code': RET.OK})
        # response.set_cookie() 不能直接存储字典数据 需要编码

        cookie_cart = base64.b64encode(pickle.dumps(cookie_cart_cart)).decode()

        response.set_cookie('carts', cookie_cart)
        print(cookie_cart)
        return response

    def get(self, request):

        # 判断用户状态
        if request.user.is_authenticated:

            redis_conn = get_redis_connection('carts')
            cart_dict = redis_conn.hgetall('carts_%s' % request.user.id)
            sku_ids = set()
            sku_idss = redis_conn.smembers('selected_%s' % request.user.id)
            # 拼接数据
            for i in sku_idss:
                sku_ids.add(i.decode())
            print(sku_ids)
            sku_list = []
            for sku_id, count in cart_dict.items():
                sku_id = sku_id.decode()
                count = count.decode()
                print(sku_id, count)
                print(type(sku_id), type(count))
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    'id': sku.id,
                    'default_image_url': sku.default_image_url.url,
                    'name': sku.name,
                    'price': str(sku.price),
                    'count': int(count),
                    'amount': str(int(count) * sku.price),
                    'selected': str(sku_id in sku_ids),
                }
                sku_list.append(sku_dict)
            print(len(sku_list))
            print(sku_list)
            return render(request, 'cart.html', context={'cart_skus': sku_list})
        else:
            # 获取cookie购物车数据
            cookie_carts = request.COOKIES.get('carts')
            # 字符串转字典
            cookie_carts_dict = {}
            if cookie_carts:
                cookie_carts_dict = pickle.loads(base64.b64decode(cookie_carts.encode()))
            print(cookie_carts_dict)
            # 拼接数据
            sku_list = []
            for sku_id, selected_count in cookie_carts_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    'id': sku.id,
                    'default_image_url': sku.default_image_url.url,
                    'name': sku.name,
                    'price': str(sku.price),
                    'count': int(selected_count['count']),
                    'amount': str(int(selected_count['count']) * sku.price),
                    'selected': str(selected_count['selected']),
                }
                sku_list.append(sku_dict)
            # 返回响应
            return render(request, 'cart.html', context={'cart_skus': sku_list})

    def put(self, request):
        data_dict = json.loads(request.body)
        sku_id = data_dict.get('sku_id')
        count = data_dict.get('count')
        selected = data_dict.get('selected')
        print(data_dict)
        # 校验参数
        if not all([sku_id, count]):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '参数不全'})

        # 判断count是否为整数
        try:
            count = int(count)
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RET.DATAERR, 'errmsg': '数量有误'})

        # 判断selected是否为bool类型
        try:
            selected = bool(selected)
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RET.DATAERR, 'errmsg': '状态有误'})

        # 判断商品是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            print(e)
            return http.JsonResponse({'code': RET.DBERR, 'errmsg': '商品不存在'})

        # 判断库存是否足够
        if count > sku.stock:
            return http.JsonResponse({'code': RET.DATAERR, 'errmsg': '库存不足'})

        # 判断用户状态，数据保存
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')

            # 修改数据
            redis_conn.hset('carts_%s' % request.user.id, sku_id, count)

            if selected:
                redis_conn.sadd('selected_%s' % request.user.id, sku_id)
            else:
                redis_conn.srem('selected_%s' % request.user.id, sku_id)

            # 拼接数据，返回响应
            cart_sku = {
                'id': sku.id,
                'default_image_url': sku.default_image_url.url,
                'name': sku.name,
                'price': sku.price,
                'count': int(count),
                'amount': str(int(count) * sku.price),
                'selected': selected,
            }

            return http.JsonResponse({'code': RET.OK, 'cart_sku': cart_sku})
        else:
            # 获取cookie购物车数据
            cookie_carts = request.COOKIES.get('carts')
            # 字符串转字典
            cookie_carts_dict = {}
            if cookie_carts:
                cookie_carts_dict = pickle.loads(base64.b64decode(cookie_carts.encode()))
            print(cookie_carts_dict)
            cookie_carts_dict[sku_id] = {
                'count': count,
                'selected': selected,
            }
            cart_sku = {
                    'id': sku.id,
                    'default_image_url': sku.default_image_url.url,
                    'name': sku.name,
                    'price': str(sku.price),
                    'count': int(count),
                    'amount': str(int(count) * sku.price),
                    'selected': selected,
            }
            response = http.JsonResponse({'code': RET.OK, 'cart_sku': cart_sku})
            cookie_cart = base64.b64encode(pickle.dumps(cookie_carts_dict)).decode()
            response.set_cookie('carts', cookie_cart)
            return response

    def delete(self, request):
        data_dict = json.loads(request.body)
        sku_id = data_dict.get('sku_id')

        if not sku_id:
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '参数不全'})

        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            redis_conn.hdel('carts_%s' % request.user.id, sku_id)
            redis_conn.srem('selected_%s' % request.user.id, sku_id)
            return http.JsonResponse({'code': RET.OK})
        else:
            # 获取cookie购物车数据
            cookie_carts = request.COOKIES.get('carts')
            # 字符串转字典
            cookie_carts_dict = {}
            if cookie_carts:
                cookie_carts_dict = pickle.loads(base64.b64decode(cookie_carts.encode()))

            if sku_id in cookie_carts_dict:
                del cookie_carts_dict[sku_id]

            response = http.JsonResponse({'code': RET.OK})
            cookie_cart = base64.b64encode(pickle.dumps(cookie_carts_dict)).decode()
            response.set_cookie('carts', cookie_cart)
            return response


class CartsAllSelectedView(View):

    def put(self, request):
        data_dict = json.loads(request.body)
        selected = data_dict.get('selected')

        try:
            selected = bool(selected)
        except Exception as e:
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '参数有误'})

        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            sku_ids = redis_conn.hkeys('carts_%s' % request.user.id)
            print(sku_ids)
            if selected:
                redis_conn.sadd('selected_%s' % request.user.id, *sku_ids)
            else:
                redis_conn.srem('selected_%s' % request.user.id, *sku_ids)
            return http.JsonResponse({'code': RET.OK})
        else:
            cookie_cart = request.COOKIES.get('carts')

            cookie_cart_dict = {}
            if cookie_cart:
                cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))
            print(cookie_cart_dict)
            # 数据全选，或者全不选
            for sku_id, selected_count in cookie_cart_dict.items():
                selected_count['selected'] = selected

            response = http.JsonResponse({'code': RET.OK})
            cookie_cart = base64.b64encode(pickle.dumps(cookie_cart_dict)).decode()
            response.set_cookie('carts', cookie_cart)
            return response


class CartsSimpleView(View):

    def get(self, request):
        print(request.user.is_authenticated)
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            cart_dict = redis_conn.hgetall('carts_%s' % request.user.id)
            sku_ids = redis_conn.smembers('selected_%s' % request.user.id)
            print(cart_dict)
            sku_list = []
            for sku_id, count in cart_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    'id': sku.id,
                    'default_image_url': sku.default_image_url.url,
                    'name': sku.name,
                    'price': str(sku.price),
                    'count': int(count),
                    'amount': str(int(count) * sku.price),
                    'selected': sku_id in sku_ids,
                }
                sku_list.append(sku_dict)
            return http.JsonResponse({'cart_skus': sku_list})
        else:
            cookie_cart = request.COOKIES.get('carts')
            cookie_cart_dict = {}
            if cookie_cart:
                cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))
            print(cookie_cart_dict)
            sku_list = []

            for sku_id, selected_count in cookie_cart_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    'id': sku.id,
                    'default_image_url': sku.default_image_url.url,
                    'name': sku.name,
                    'price': str(sku.price),
                    'count': int(selected_count['count']),
                    'amount': str(int(selected_count['count']) * sku.price),
                    'selected': selected_count['selected'],
                }
                sku_list.append(sku_dict)
            return http.JsonResponse({'cart_skus': sku_list})